home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SPACE 2
/
SPACE - Library 2 - Volume 1.iso
/
misc
/
40
/
zap3.c
< prev
Wrap
C/C++ Source or Header
|
1986-07-17
|
6KB
|
263 lines
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* zap.c - version 1.0.3 */
#include "hack.h"
extern struct obj *mkobj_at();
extern struct monst *makemon(), *mkmon_at(), youmonst;
extern struct monst *bhit();
extern char *exclam();
extern char *fl[];
/* type == -1: monster spitting fire at you */
/* type == -1,-2,-3: bolts sent out by wizard */
/* called with dx = dy = 0 with vertical bolts */
buzz(type,sx,sy,dx,dy)
register int type;
register xchar sx,sy;
register int dx,dy;
{
int abstype = abs(type);
register char *fltxt = (type == -1) ? "blaze of fire" : fl[abstype];
struct rm *lev;
xchar range;
struct monst *mon;
if(u.uswallow) {
register int tmp;
if(type < 0) return;
tmp = zhit(u.ustuck, type);
pline("The %s rips into %s%s",
fltxt, mon_nam(u.ustuck), exclam(tmp));
return;
}
if(type < 0) pru();
range = rn1(7,7);
Tmp_at2(-1, dirlet(dx,dy)); /* open call */
while(range-- > 0) {
sx += dx;
sy += dy;
if((lev = &levl[sx][sy])->typ) Tmp_at2(sx,sy);
else {
int bounce = 0;
if(cansee(sx-dx,sy-dy))
pline("The %s bounces!", fltxt);
if(ZAP_POS(levl[sx][sy-dy].typ))
bounce = 1;
if(ZAP_POS(levl[sx-dx][sy].typ)) {
if(!bounce || rn2(2)) bounce = 2;
}
switch(bounce){
case 0:
dx = -dx;
dy = -dy;
continue;
case 1:
dy = -dy;
sx -= dx;
break;
case 2:
dx = -dx;
sy -= dy;
break;
}
Tmp_at2(-2,dirlet(dx,dy));
continue;
}
if(lev->typ == POOL && abstype == 1 /* fire */) {
range -= 3;
lev->typ = ROOM;
if(cansee(sx,sy)) {
mnewsym(sx,sy);
pline("The water evaporates.");
} else
pline("You hear a hissing sound.");
}
if((mon = m_at(sx,sy)) &&
(type != -1 || mon->data->mlet != 'D')) {
wakeup(mon);
if(rnd(20) < 18 + mon->data->ac) {
register int tmp = zhit(mon,abstype);
if(mon->mhp < 1) {
if(type < 0) {
if(cansee(mon->mx,mon->my))
pline("%s is killed by the %s!",
Monnam(mon), fltxt);
mondied(mon);
} else
killed(mon);
} else
hit(fltxt, mon, exclam(tmp));
range -= 2;
} else
miss(fltxt,mon);
} else if(sx == u.ux && sy == u.uy) {
nomul(0);
if(rnd(20) < 18+u.uac) {
register int dam = 0;
range -= 2;
pline("The %s hits you!",fltxt);
switch(abstype) {
case 0:
dam = d(2,6);
break;
case 1:
if(Fire_resistance)
pline("You don't feel hot!");
else dam = d(6,6);
if(!rn2(3))
burn_scrolls();
break;
case 2:
nomul(-rnd(25)); /* sleep ray */
break;
case 3:
if(Cold_resistance)
pline("You don't feel cold!");
else dam = d(6,6);
break;
case 4:
u.uhp = -1;
}
losehp(dam,fltxt);
} else pline("The %s whizzes by you!",fltxt);
stop_occupation();
}
if(!ZAP_POS(lev->typ)) {
int bounce = 0, rmn;
if(cansee(sx,sy)) pline("The %s bounces!",fltxt);
range--;
if(!dx || !dy || !rn2(20)){
dx = -dx;
dy = -dy;
} else {
if(ZAP_POS(rmn = levl[sx][sy-dy].typ) &&
(IS_ROOM(rmn) || ZAP_POS(levl[sx+dx][sy-dy].typ)))
bounce = 1;
if(ZAP_POS(rmn = levl[sx-dx][sy].typ) &&
(IS_ROOM(rmn) || ZAP_POS(levl[sx-dx][sy+dy].typ)))
if(!bounce || rn2(2))
bounce = 2;
switch(bounce){
case 0:
dy = -dy;
dx = -dx;
break;
case 1:
dy = -dy;
break;
case 2:
dx = -dx;
break;
}
Tmp_at2(-2, dirlet(dx,dy));
}
}
}
Tmp_at2(-1,-1);
}
zhit(mon,type) /* returns damage to mon */
register struct monst *mon;
register type;
{
register int tmp = 0;
switch(type) {
case 0: /* magic missile */
tmp = d(2,6);
break;
case -1: /* Dragon blazing fire */
case 1: /* fire */
if(index("Dg", mon->data->mlet)) break;
tmp = d(6,6);
if(index("YF", mon->data->mlet)) tmp += 7;
break;
case 2: /* sleep*/
mon->mfroz = 1;
break;
case 3: /* cold */
if(index("YFgf", mon->data->mlet)) break;
tmp = d(6,6);
if(mon->data->mlet == 'D') tmp += 7;
break;
case 4: /* death*/
if(index(UNDEAD, mon->data->mlet)) break;
tmp = mon->mhp+1;
break;
}
mon->mhp -= tmp;
return(tmp);
}
#define CORPSE_I_TO_C(otyp) (char) ((otyp >= DEAD_ACID_BLOB)\
? 'a' + (otyp - DEAD_ACID_BLOB)\
: '@' + (otyp - DEAD_HUMAN))
revive(obj)
register struct obj *obj;
{
register struct monst *mtmp;
if(obj->olet == FOOD_SYM && obj->otyp > CORPSE) {
/* do not (yet) revive shopkeepers */
/* Note: this might conceivably produce two monsters
at the same position - strange, but harmless */
mtmp = mkmon_at(CORPSE_I_TO_C(obj->otyp),obj->ox,obj->oy);
delobj(obj);
}
return(!!mtmp); /* TRUE if some monster created */
}
rloco(obj)
register struct obj *obj;
{
register tx,ty,otx,oty;
otx = obj->ox;
oty = obj->oy;
do {
tx = rn1(COLNO-3,2);
ty = rn2(ROWNO);
} while(!goodpos(tx,ty));
obj->ox = tx;
obj->oy = ty;
if(cansee(otx,oty))
newsym(otx,oty);
}
fracture_rock(obj) /* fractured by pick-axe or wand of striking */
register struct obj *obj; /* no texts here! */
{
/* unpobj(obj); */
obj->otyp = ROCK;
obj->quan = 7 + rn2(60);
obj->owt = weight(obj);
obj->olet = WEAPON_SYM;
if(cansee(obj->ox,obj->oy))
prl(obj->ox,obj->oy);
}
burn_scrolls()
{
register struct obj *obj, *obj2;
register int cnt = 0;
for(obj = invent; obj; obj = obj2) {
obj2 = obj->nobj;
if(obj->olet == SCROLL_SYM) {
cnt++;
useup(obj);
}
}
if(cnt > 1) {
pline("Your scrolls catch fire!");
losehp(cnt, "burning scrolls");
} else if(cnt) {
pline("Your scroll catches fire!");
losehp(1, "burning scroll");
}
}